package com.github.livebase.database;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.ArrayMap;

import androidx.annotation.Nullable;

import com.github.livebase.event.EventBus;
import com.github.livebase.event.EventListener;
import com.github.livebase.event.SimpleEventBus;

import java.util.Map;

/**
 * @ClassName LiveDatabaseHelper
 * @description:
 * @author: biao532
 * @create: 2023-12-27 10:35
 * @Version 1.0
 **/
public class LiveDatabaseHelper extends SQLiteOpenHelper {
    private Map<Class, Object> map = new ArrayMap<>();
    private OperatorHelper helper;
    public LiveDatabaseHelper(@Nullable Context context, int version) {
        this(context, null, version);
    }
    public LiveDatabaseHelper(@Nullable Context context, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, "live.db", factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTable = "create table `epgs_info`(`channelId` VARCHAR(12), `start` integer, `end` integer, `title` VARCHAR(40))";
        db.execSQL(createTable);

        createTable = "create table `booking`(`e_time` integer, `type` VARCHAR(32), `i_time` integer, `message` VARCHAR(512))";
        db.execSQL(createTable);

        //  owner(数据所有者), key, version(版本), value, clazz(value 类型), expire(有效期/6089.01.01 00:00:00为永久有效，需定时清除)
        createTable = "create table `live_storage`(`owner` VARCHAR(32)  NOT NULL, `key` VARCHAR(64)  NOT NULL, `version` integer  NOT NULL, `value` BLOB, `clazz` VARCHAR(256), `expire` integer, " +
                "CONSTRAINT pk PRIMARY KEY (`owner`, `key`, `version`) )";
        db.execSQL(createTable);
    }

    private void delete(SQLiteDatabase db) {
        deleteExits(db, "epgs_info");
        deleteExits(db, "booking");
        deleteExits(db, "live_storage");
    }
    private void deleteExits(SQLiteDatabase database, String tableName) {
        try {
            database.rawQuery(String.format("select 1 from `%s`", tableName), null).close();
            String delete = String.format("DROP TABLE `%s`", tableName);
            database.execSQL(delete);
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (oldVersion == newVersion) {
            return;
        }
        delete(db);
        this.onCreate(db);
    }

    public OperatorHelper operatorHelper() {
        if (helper == null) {
            synchronized (LiveDatabaseHelper.class) {
                if (helper == null) {
                    this.helper = new OperatorHelper(this);
                }
            }
        }
        return helper;
    }
    public EpgOperator getEpg() {
        Object epg = map.get(EpgOperator.class);
        if (epg == null) {
            synchronized (map) {
                epg = map.get(EpgOperator.class);
                if (epg == null) {
                    epg = new EpgOperator(this);
                    map.put(EpgOperator.class, epg);
                }
            }
        }
        return (EpgOperator) epg;
    }

    public BookingOperator getBooking() {
        Object epg = map.get(BookingOperator.class);
        if (epg == null) {
            synchronized (map) {
                epg = map.get(BookingOperator.class);
                if (epg == null) {
                    epg = new BookingOperator(this);
                    map.put(BookingOperator.class, epg);
                }
            }
        }
        return (BookingOperator) epg;
    }

    public StorageOperator getStorageOperator() {
        Object operator = map.get(StorageOperator.class);
        if (operator == null) {
            synchronized (map) {
                operator = map.get(StorageOperator.class);
                if (operator == null) {
                    operator = new StorageOperator(this.operatorHelper());
                    SimpleEventBus.getDefault().register(EventBus.EVENT_CHANGE_DATE, (EventListener) operator, true);
                    map.put(StorageOperator.class, operator);
                }
            }
        }
        return (StorageOperator)operator;
    }

    @Override
    public void close() {
        super.close();
        StorageOperator operator = getStorageOperator();
        SimpleEventBus.getDefault().unregister(EventBus.EVENT_CHANGE_DATE, operator);
        map.clear();
    }
}
